

//================================================================================
LOCO_FORCE_INLINE Vector3::Vector3(float x_value, float y_value, float z_val) : x(x_value), y(y_value), z(z_val)
{

}

//================================================================================
LOCO_FORCE_INLINE Vector3::Vector3(float value) : x(value), y(value), z(value)
{

}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::operator-() const
{
	return Vector3(-x, -y, -z);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::operator+(Vector3 const& in) const
{
	return Vector3(x + in.x, y + in.y, z + in.z);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::operator-(Vector3 const& in) const
{
	return Vector3(x - in.x, y - in.y, z - in.z);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::operator*(Vector3 const& in) const
{
	return Vector3(x * in.x, y * in.y, z * in.z);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::operator/(Vector3 const& in) const
{
	return Vector3(x / in.x, y / in.y, z / in.z);
}

//================================================================================
LOCO_FORCE_INLINE Vector3& Vector3::operator+=(Vector3 const& in)
{
	x += in.x;
	y += in.y;
	z += in.z;
	return *this;
}

//================================================================================
LOCO_FORCE_INLINE Vector3& Vector3::operator-=(Vector3 const& in)
{
	x -= in.x;
	y -= in.y;
	z -= in.z;
	return *this;
}

//================================================================================
LOCO_FORCE_INLINE Vector3& Vector3::operator*=(Vector3 const& in)
{
	x *= in.x;
	y *= in.y;
	z *= in.z;
	return *this;
}

//================================================================================
LOCO_FORCE_INLINE Vector3& Vector3::operator/=(Vector3 const& in)
{
	x /= in.x;
	y /= in.y;
	z /= in.z;
	return *this;
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator==(Vector3 const& in) const
{
	return (x == in.x) && (y == in.y) && (z == in.z);
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator!=(Vector3 const& in) const
{
	return (x != in.x) || (y != in.y) || (z != in.z);
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator>(Vector3 const& in) const
{
	return (x > in.x) && (y > in.y) && (z > in.z);
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator<(Vector3 const& in) const
{
	return (x < in.x) && (y < in.y) && (z < in.z);
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator>=(Vector3 const& in) const
{
	return (x >= in.x) && (y >= in.y) && (z >= in.z);
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::operator<=(Vector3 const& in) const
{
	return (x <= in.x) && (y <= in.y) && (z <= in.z);
}

//================================================================================
LOCO_FORCE_INLINE float Vector3::norm() const
{
	return sqrt(x*x + y*y + z*z);
}

//================================================================================
LOCO_FORCE_INLINE float Vector3::square_norm() const
{
	return x*x + y*y + z*z;
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::normalize() const
{
	return Vector3(x, y, z) / norm();
}

//================================================================================
LOCO_FORCE_INLINE bool Vector3::near_equal(Vector3 const& a, Vector3 const& b, float delta)
{
	return	loco::near_equal(a.x, b.x, delta) && 
			loco::near_equal(a.y, b.y, delta) && 
			loco::near_equal(a.z, b.z, delta);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::reflection(Vector3 const& in, Vector3 const& normal)
{
	return   in - normal * (2.f * Vector3::dot(in, normal));
}

//================================================================================
LOCO_FORCE_INLINE float Vector3::distance(Vector3 const& a, Vector3 const& b)
{
	return (a - b).norm();
}

//================================================================================
LOCO_FORCE_INLINE float Vector3::square_distance(Vector3 const& a, Vector3 const& b)
{
	return (a - b).square_norm();
}

//================================================================================
LOCO_FORCE_INLINE float Vector3::dot(Vector3 const& a, Vector3 const& b)
{
	return a.x*b.x + a.y*b.y + a.z*b.z;
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::cross(Vector3 const& a, Vector3 const& b)
{
	return Vector3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::lerp(Vector3 const& a, Vector3 const& b, float value)
{
	return Vector3(loco::lerp(a.x, b.x, value), loco::lerp(a.y, b.y, value), loco::lerp(a.z, b.z, value));
}

//================================================================================
LOCO_FORCE_INLINE Vector3 Vector3::lerp(Vector3 const& a, Vector3 const& b, Vector3 const& value)
{
	return Vector3(loco::lerp(a.x, b.x, value.x), loco::lerp(a.y, b.y, value.y), loco::lerp(a.z, b.z, value.z));
}
